/**
 * -----------------------------------------------------------
 *  封装单数据的获取、修改、删除、数据验证等方法
 * -----------------------------------------------------------
 * Created by zhanglihe on 15/7/8.
 *
 * 使用示例：
 *
 *  1.请求数据并输出到页面上
 *      var model = new Model();
 *      model.extend({
 *          url: 'http://api.com/resource',
 *          data: {id: xxx}, //可选
 *          render: function() {
 *              //this.data 输出数据
 *          },
 *          error: function() {} //[可选]请求失败时执行
 *      }).fetch();
 *  2.创建数据
 *      var model = new Model();
 *      model.extend({
 *          url: '',
 *          data: {},
 *          valid_config: {name: 'required'},
 *          success: function(res) {}
 *      }).post();
 */

require.config(require_config);

define([
    'jquery',
    'template'
], function ($, template) {

    var Model = function (options) {
        var defaults = {
            url: '',
            data: {}
        };
        var originalOptions = options = options || {};

        options = $.extend(true, {}, defaults, options);
        options.original = originalOptions;

        $.extend(this, options);

        this.initialize();

        return this;
    };
    Model.prototype = {
        container: '', //页面容器ID
        template: '',  //模板ID

        tag_name: 'tr', //标签类型
        class_name: '', //标签class

        //初始化
        initialize: function () {
            this.el = $('<' + this.tag_name + '></' + this.tag_name + '>');
            this.el.addClass(this.class_name);
            this.init();
        },
        //自定义初始化
        init: function () {

        },

        /** 创建 dom 对象，并绑定事件 */
        create_element: function () {
            if (typeof this.template == 'undefined' || this.template == '') {
                return this;
            }
            this.el.html(template(this.template, this.data));
            this.event_bind();
            return this;
        },

        /** 新增或更新数据 */
        save: function (ajax_type) {
            if (this.valid_config && ajax_type !== 'delete') {
                if (!this.validation()) {
                    Alert({msg: '提交失败，请确认表单项填写是否正确', type: 'error'});
                    return false;
                }
            }
            var _this = this;
            var ret = true;
            var data = typeof(this.formData) !== 'undefined' ? this.formData : this.data;
            $.ajax({
                'url': this.get_url(ajax_type),
                'type': ajax_type,
                'async': false,
                'data': data,
                'success': function (result) {
                    if (typeof(result.code) === 'undefined') {
                        _this.error('通讯错误');
                        ret = false;
                    }
                    if (result.code == 0) {
                        _this.success(result);
                    } else {
                        _this.error(result.msg);
                        ret = false;
                    }
                    _this.callback();
                }, 'error': function () {
                    _this.error('通讯错误');
                    ret = false;
                }
            });
            return ret;
        },

        get_url: function (k) {
            if (typeof this.url === 'string' || this.url.nodeType === 1) {
                return this.format_url(this.url);
            }
            if (typeof this.url[k] !== 'undefined') {
                return this.format_url(this.url[k]);
            }
        },

        //格式化url,替换{}
        format_url: function (url) {
            if (typeof this.data.id == 'undefined') {
                return url;
            }
            return url.replace(/{id}/, this.data.id);
        },

        /** 接口请求成功后执行 */
        callback: function () {
        },

        /** 请求API接口获取数据 */
        fetch: function () {
            var _this = this;
            var ret = true; //请求是否成功
            $.ajax({
                'url': this.get_url('get'),
                'type': 'get',
                'async': false,
                'data': {id: _this.data.id},
                'success': function (result) {
                    if (typeof(result.code) === 'undefined') {
                        _this.error('通讯错误');
                        ret = false;
                    }
                    if (result.code == 0) {
                        if (typeof(result.data) == 'object') {
                            _this.data = result.data;
                        }
                        _this.sync();
                        _this._set(result);
                    } else {
                        _this.error(result.msg);
                        ret = false;
                    }
                    _this.callback();
                }, 'error': function () {
                    _this.error('通讯错误');
                    ret = false;
                }
            });
            return ret;
        },

        /** 设置数据项 */
        _set: function (result) {
            this.result = result;
            this.data = result.data;
        },

        /** 设置data数据项 */
        set_data: function(key, val) {
            this.data[key] = val;
        },

        /** 获取data数据项 */
        get_data: function(key) {
            if(typeof this.data[key] === 'undefined') {
                return undefined;
            }
            return this.data[key];
        },

        /** 设置表单数据项，--formData仅用于post,put-- */
        set_form: function(key, val) {
            if(typeof this.formData === 'undefined') {
                this.formData = {};
            }
            this.formData[key] = val;
        },
        /** 获取表单数据项 */
        get_form: function(key) {
            if(typeof this.formData[key] === 'undefined') {
                return undefined;
            }
            return this.formData[key];
        },

        /** 更新数据 */
        put: function () {
            if (this.save('put')) {
                this.create_element();
                return true;
            }
            return false;
        },

        /** 创建数据 */
        post: function () {
            return this.save('post');
        },

        /** 删除本数据 */
        del: function () {
            if (this.save('delete')) {
                this.el.remove();
                return true;
            }
            return false;
        },
        delete: function () {
            if (this.save('delete')) {
                this.el.remove();
                return true;
            }
            return false;
        },

        /** 获取数据成功后执行 */
        sync: function () {
            this.create_element();
            this.render();
        },

        /** 输出数据到页面 */
        render: function () {
            $('#' + this.container).html(this.el);
            return this;
        },

        /** 注册事件 */
        event_bind: function () {
            if (typeof(this.event) === 'undefined') {
                return;
            }
            for (var id in this.event) {
                this.event_live(id);
            }
        },
        event_live: function (id) {
            var _this = this;
            var arr = id.split(':');
            if (arr.length == 1) {
                arr[1] = 'click';
            }
            if (arr[1] == 'mouseover') {
                this.el.find(arr[0]).mouseover(arr[1], function (e) {
                    _this[_this.event[id]](e, this);
                });
                return true;
            }
            if (arr[1] == 'mouseout') {
                this.el.find(arr[0]).mouseout(arr[1], function (e) {
                    _this[_this.event[id]](e, this);
                });
                return true;
            }
            this.el.find(arr[0]).on(arr[1], function (e) {
                _this[_this.event[id]](e, $(this));
            });
            return true;
        },

        /** 请求接口成功时执行 */
        success: function (result) {
            if (typeof(Alert) !== 'undefined') {
                Alert({msg: '操作成功'});
            } else {
                alert('操作成功');
            }
        },
        /** 请求接口失败时执行 */
        error: function (msg) {
            if (typeof(Alert) !== 'undefined') {
                Alert({msg: msg, type: 'error'});
            } else {
                alert(msg);
            }
        },

        /**
         * 表单验证配置, 示例{'name': 'number'}
         * --name 对应表单项name
         * --表单项添加data-error-msg 属性可自定义错误信息
         *
         */
        valid_config: {},

        /** 表单验证方法 */
        validation: function () {
            var _this = this;
            var valid_format = {
                email: function (item) {
                    if (item == '' || item === undefined || item === null) {
                        return false;
                    }
                    var Reg = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
                    return Reg.test(item);
                },
                number: function (item) {
                    if (item == '' || item === undefined || item === null) {
                        return false;
                    }
                    var Reg = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/;
                    return Reg.test(item);
                },
                required: function (item) {
                    return !( (typeof item == 'object' && typeof item.length !== 'undefined' && item.length == 0) || item == '' || item === undefined || item === null);
                },
                array: function(item) {
                    console.log(item);
                    return !(typeof item.length == 'undefined' || item.length == 0);
                },
                price: function(item) {
                    return (item != '' && item >0);
                }
                //TODO 验证待完善...
            };
            var valid_message = {
                email: '邮箱地址格式不正确',
                number: '请输入正确的值',
                required: '这里不能留空哦',
                array: '这里不能留空哦',
                price: '价格为空或格式错误'
            };

            var get_valid_message = function (name, item) {
                var msg = $('[name="' + name + '"]').attr("data-error-msg");
                if (typeof(msg) !== "undefined") {
                    return msg;
                }
                if(typeof valid_message[item] !== 'undefined') {
                    return valid_message[item];
                }
                return '格式错误';
            };

            var valid_error = function (name, item) {
                var dom = $('[name="' + name + '"]').parent();
                if (dom.hasClass('has-error')) {
                    return;
                }
                dom.addClass('has-error').append('<span class="label label-warning error-msg">' + get_valid_message(name, item) + '</span>');
                $('[name="' + name + '"]').on('blur', function () {
                    valid_check(name, item);
                });
            };

            var valid_success = function (name) {
                $('[name="' + name + '"]').parent().removeClass('has-error').find('.error-msg').remove();
            };

            var valid_check = function (index, item) {
                if(typeof item === 'function') {
                    if(item(_this, get_value(index))) {
                        valid_success(index);
                        return true;
                    } else {
                        valid_error(index, item);
                        return false;
                    }
                }

                if (typeof(valid_format[item]) !== 'undefined') {
                    if (!valid_format[item](get_value(index))) {
                        valid_error(index, item);
                        return false;
                    } else {
                        valid_success(index);
                    }
                }
                return true;
            };

            var get_value = function(index) {
                return _this.get_data(index) ? _this.get_data(index) : $('[name="' + index + '"]').val();
            };

            if (this.valid_config) {
                var valid = true;
                $.each(this.valid_config, function (index, item) {
                    if(!valid_check(index, item)) {
                        valid = false;
                    }
                });
                return valid;
            }
            return true;
        }
    };

    return Model;
});